package com.zhangh.summer.admin.support.ds.es;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.zhangh.summer.admin.support.ds.common.pager.DataPager;
import com.zhangh.summer.admin.support.ds.common.pager.Pager;
import com.zhangh.summer.admin.support.utils.json.JsonEncoder;
import com.zhangh.summer.admin.support.ds.es.annotation.IndexId;
import com.zhangh.summer.admin.support.ds.es.annotation.IndexMapper;
import com.zhangh.summer.admin.support.ds.es.annotation.IndexName;
import com.zhangh.summer.admin.support.ds.es.base.EsIterator;
import com.zhangh.summer.admin.support.ds.es.mapper.EsMapperParser;
import com.esotericsoftware.reflectasm.MethodAccess;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.entity.ContentType;
import org.apache.http.nio.entity.NStringEntity;
import org.apache.http.util.EntityUtils;
import org.elasticsearch.client.Request;
import org.elasticsearch.client.Response;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.rest.RestRequest;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.*;

@Slf4j
public class Es7xClient implements IEsClient {
    private static final String KEY_TOTAL="total";
    private static final String KEY_ROWS="rows";
    private RestClient restClient;
    private static long  MAX_RESULT_WINDOW=0L;
    private String index;
    private String type="_doc";

    public Es7xClient(RestClient restClient){
        this.restClient=restClient;
    }

    public Es7xClient(RestClient restClient, String index){
        this.restClient=restClient;
        this.index=index;
    }
    /*public Es7xClient(RestClient restClient, String index, String type){
        this.restClient=restClient;
        this.index=index;
        //this.type=type;
    }*/

    /**
     * 通过query查询结果
     * @param query 查询json串
     * @param cls 对象bean class
     * @param <M> 对象
     * @return
     */
    public <M> String selectResponse(String query,Class<M> cls){
        log.debug(query);
        String indexName=getIndex(cls);
        String type = getType(cls);
        HttpEntity entity = new NStringEntity(query, ContentType.APPLICATION_JSON);
        try {
            String endpoint ="/" + indexName + "/" + type + "/_search";
            if (StringUtils.isBlank(type)){
                endpoint ="/" + indexName  + "/_search";
            }
            Request request =new Request(RestRequest.Method.GET.name(),endpoint);
            request.setEntity(entity);
            Response response = restClient.performRequest(request);
            String responseBody = EntityUtils.toString(response.getEntity());
            return responseBody;

        }catch (Exception e){
            log.error("query es error:{}",e.getMessage());
        }
        return null;
    }

    /**
     * 通过queryId查询结果
     * @param queryId 查询ID，配置在xml中的query里的id
     * @param params 参数
     * @param cls
     * @param <M>
     * @return
     */
    public <M> String selectResponse(String queryId,Map<String,Object> params,Class<M> cls){
        String query=buildQuery(queryId,params,cls);
        log.debug(query);
        String result= selectResponse( query,cls);
        return result;
    }


    /**
     * 通过query查询结果集合
     * @param query 查询json串
     * @param cls
     * @param <M>
     * @return
     */
    public <M> List<M> selectList(String query,Class<M> cls){
        String responseBody=selectResponse(query,cls);
        Map<String,Object> resultMap=handlerResponseBody(responseBody,cls);
        return  (List)resultMap.get(KEY_ROWS);
    }

    /**
     * 通过queryId查询结果集合
     * @param queryId 查询ID，配置在xml中的query里的id
     * @param params 参数
     * @param cls
     * @param <M>
     * @return
     */
    public<M> List<M> selectList(String queryId,Map<String,Object> params,Class<M> cls){
        String query=buildQuery(queryId,params,cls);
        return selectList(query,cls);
    }

    @Override
    public <M> List<M> selectList(String queryId, Map<String, Object> params, Pager pager, Class<M> cls) {
        String query=buildQuery(queryId,params,cls);
        query=queryAddPager(query,pager);
        return selectList(query,cls);
    }

    /**
     * 通过query查询第一条数据
     * @param query 查询json串
     * @param cls
     * @param needPager 是否需要分页
     * @param <M>
     * @return
     */
    public <M> M selectFirst(String query,Class<M> cls,boolean needPager){
        if (needPager){
            Pager pager=new Pager(1,1);
            query=queryAddPager(query,pager);
        }
        List<M> list=selectList(query,cls);
        if (null!=list&&list.size()>0){
            return list.get(0);
        }
        return null;
    }

    /**
     * 通过queryId查询第一条数据
     * @param queryId 查询ID，配置在xml中的query里的id
     * @param params 参数
     * @param cls
     * @param <M>
     * @return
     */
    public<M> M selectFirst(String queryId,Map<String,Object> params,Class<M> cls){
        String query=buildQuery(queryId,params,cls);
        return selectFirst(query,cls,true);
    }

    /**
     * 通过主键查询
     * @param key 主键
     * @param cls
     * @param <M>
     * @return
     */
    public <M> M selectByPrimaryKey(String key,Class<M> cls){
        JSONObject queryJSON=new JSONObject();
        JSONObject constant_scoreJSON=new JSONObject();
        JSONObject filterJSON=new JSONObject();
        JSONObject termJSON=new JSONObject();
        JSONObject keyJSON=new JSONObject();
        keyJSON.put("_id",key);

        termJSON.put("term",keyJSON);
        filterJSON.put("filter",termJSON);
        constant_scoreJSON.put("constant_score",filterJSON);
        queryJSON.put("query",constant_scoreJSON);
        String query=queryJSON.toJSONString();

        M m=this.selectFirst(query,cls,false);
        return m;
    }

    /**
     * 通过query分页查询
     * @param query 查询json
     * @param pager 分页
     * @param cls
     * @param <E>
     * @return
     */
    public <E> DataPager<E> selectDataPager (String query, Pager pager, Class<E> cls){
        query=queryAddPager(query,pager);
        pager=resetPager(pager);
        String responseBody=selectResponse(query,cls);
        Map<String,Object> resultMap=handlerResponseBody(responseBody,cls);
        List<E> rows= (List<E>) resultMap.get(KEY_ROWS);
        int totalSize= (int) resultMap.get(KEY_TOTAL);
        return new DataPager<E>(rows,totalSize,pager);
    }

    /**
     * 通过queryId分页查询
     * @param queryId 查询ID
     * @param params 参数
     * @param pager 分页
     * @param cls
     * @param <M>
     * @return
     */
    public <M> DataPager<M> selectDataPager (String queryId,Map<String,Object> params,Pager pager,Class<M> cls){
        String query=buildQuery(queryId,params,cls);
        return selectDataPager(query,pager,cls);
    }

    /**
     * 通过分页ID迭代查询
     * @param queryId 查询ID
     * @param params 参数
     * @param size 迭代数据大小，为0 默认10
     * @param scroll 为空，默认1m
     * @param cls
     * @param <E>
     * @return
     */
    public<E> EsIterator<E> selectEsIterator(String queryId, Map<String,Object> params, int size, String scroll, Class<E> cls){
        if (size==0){
            size=10;
        }
        if(StringUtils.isEmpty(scroll)){
            scroll="1m";
        }
        String query=buildQuery(queryId,params,cls);

        JSONObject queryJson = JSON.parseObject(query);
        queryJson.fluentPut("size",size);
        query=queryJson.toJSONString();
       log.debug(query);

        String indexName=getIndex(cls);
        String type = getType(cls);

        try {
            HttpEntity entity = new NStringEntity(query, ContentType.APPLICATION_JSON);
            String endpoint="/" + indexName + "/" + type + "/_search?scroll=" + scroll + "";
            Request request =new Request(RestRequest.Method.GET.name(),endpoint);
            request.setEntity(entity);
            Response response = restClient.performRequest(request);
            String responseBody = EntityUtils.toString(response.getEntity());
            if (null != responseBody) {
                JSONObject responseObject = JSON.parseObject(responseBody);
                String scrollId = responseObject.get("_scroll_id").toString();
                JSONObject hitsObject = JSON.parseObject(responseObject.get("hits").toString());//外层hits
                long totalSize = hitsObject.getLong("total");
                List<E> rows = new ArrayList<>();
                if (totalSize > 0) {
                    JSONArray hitsArray = JSON.parseArray(hitsObject.get("hits").toString());//内部hits
                    if (hitsArray.size() > 0) {
                        for (int i = 0; i < hitsArray.size(); i++) {
                            JSONObject row = hitsArray.getJSONObject(i);
                            String _source = row.get("_source").toString();
                            String _id = row.get("_id").toString();
                            _source = mapperJson(_id, _source, cls, true);

                            E en = JsonEncoder.DEFAULT.decode(_source, cls);
                            rows.add(en);
                        }
                    }
                }
                EsIterator<E> esIterator = new EsIterator<E>(scroll, scrollId, this, totalSize, rows, cls);
                return esIterator;
            }
        }catch (Exception e){
            log.error("query es error:{}",e.getMessage());
        }
        return null;
    }

    /**
     * 通过scroll 迭代查询
     * @param scroll
     * @param scrollId
     * @param cls
     * @param <E>
     * @return
     */
    public<E> List<E> selectScroll(String scroll,String scrollId,Class<E> cls){
        JSONObject object=new JSONObject();
        object.put("scroll",scroll);
        object.put("scroll_id",scrollId);
        String query=object.toJSONString();
        log.debug(query);

        try {
            HttpEntity entity = new NStringEntity(query, ContentType.APPLICATION_JSON);
            String endpoint="/_search/scroll";
            Request request =new Request(RestRequest.Method.GET.name(),endpoint);
            request.setEntity(entity);
            Response response = restClient.performRequest(request);
            String responseBody = EntityUtils.toString(response.getEntity());

            if (null != responseBody) {
                JSONObject responseObject = JSON.parseObject(responseBody);
                scrollId = responseObject.get("_scroll_id").toString();
                JSONObject hitsObject = JSON.parseObject(responseObject.get("hits").toString());//外层hits
                long totalSize = hitsObject.getLong("total");
                List<E> rows = new ArrayList<>();
                if (totalSize > 0) {
                    JSONArray hitsArray = JSON.parseArray(hitsObject.get("hits").toString());//内部hits
                    if (hitsArray.size() > 0) {
                        for (int i = 0; i < hitsArray.size(); i++) {
                            JSONObject row = hitsArray.getJSONObject(i);
                            String _source = row.get("_source").toString();
                            String _id = row.get("_id").toString();
                            _source = mapperJson(_id, _source, cls, true);

                            E en = JsonEncoder.DEFAULT.decode(_source, cls);
                            rows.add(en);
                        }
                    }
                }
                return rows;
            }
        }catch (Exception e){
            log.error("query es error:{}",e.getMessage());
        }
        return null;
    }


    /**
     * 通过query查询总数据
     * @param query 查询json
     * @param cls
     * @param <M>
     * @return
     */
    public <M> Long count(String query,Class<M> cls){
        Pager pager=new Pager(1,1);
        query=queryAddPager(query,pager);
        String responseBody=selectResponse(query,cls);
        Map<String,Object> resultMap=this.handlerResponseBody(responseBody,cls);
        if (null!=resultMap.get(KEY_TOTAL)){
            return (long)resultMap.get(KEY_TOTAL);
        }
        return Long.valueOf(0);
    }

    /**
     * 通过queryId 查询总数
     * @param queryId 查询ID
     * @param params 参数
     * @param cls
     * @param <M>
     * @return
     */
    public <M> Long count(String queryId,Map<String,Object> params,Class<M> cls){
        String query=buildQuery(queryId,params,cls);
        return count(query,cls);
    }

    /**
     * 插入数据
     * @param m 数据对象
     * @param <M>
     */
    public <M> void insert(M m){
        String indexName=getIndex(m.getClass());
        String type = getType(m.getClass());

        //反射取得ID注解的值
        String id=getId(m).toString();
        String dataJson=JsonEncoder.DEFAULT.encode(m);
        dataJson=mapperJson(null,dataJson,m.getClass(),false);
        String method = "PUT";
        String endpoint = "/"+indexName+"/"+type+"";
        if (null!=id){
            endpoint = "/"+indexName+"/"+type+"/"+id;
        }
        try {
            HttpEntity insertEntity = new NStringEntity(dataJson, ContentType.APPLICATION_JSON);
            Request request =new Request(RestRequest.Method.PUT.name(),endpoint);
            request.setEntity(insertEntity);
            Response insertResponse = restClient.performRequest(request);
        }catch (Exception e){
            log.error("insert es error:{}",e.getMessage());
        }
    }

    @Override
    public <T> void insertOrUpdate(T t) {
        String indexName=getIndex(t.getClass());
        String type = getType(t.getClass());

        //反射取得ID注解的值
        String id=getId(t).toString();
        String method = "POST";
        String endpoint = "/"+indexName+"/"+type+"/"+id+"/_update";
        try {
            //String dataJson=JsonEncoder.DEFAULT.encode(m);
            String dataJson = mapperJson(null,JsonEncoder.DEFAULT.encode(t),t.getClass(),false);

            JSONObject updateObject=new JSONObject();
            updateObject.put("doc", JSONObject.parse(dataJson));
            updateObject.put("doc_as_upsert",true);
            String json=updateObject.toJSONString();

            HttpEntity entity = new NStringEntity(json, ContentType.APPLICATION_JSON);
            Request request =new Request(RestRequest.Method.POST.name(),endpoint);
            request.setEntity(entity);
            Response response = restClient.performRequest(request);

            String responseBody = EntityUtils.toString(response.getEntity());
            JSONObject responseObject = JSON.parseObject(responseBody);
            boolean errors= (boolean)(responseObject.get("errors") != null?responseObject.get("errors"):false);
            if (errors){
                log.error("update or insert es error，error is："+(String)responseObject.get("items"));
                throw  new RuntimeException("update or insert es error，error is "+(String)responseObject.get("items"));
            }
        }catch (Exception e){
            log.error("update or insert es error:{}",e.getMessage());
            throw  new RuntimeException("update or insert es error，error is "+e.getMessage());
        }
    }

    @Override
    public <T> void batchInsertOrUpdate(List<T> list,Class<T> cls) {
        String indexName=getIndex(cls);
        String type = getType(cls);

        String method = "POST";
        String endpoint = "/"+indexName+"/"+type+"/_bulk";
        try {
            String queryBody="";

            for (T t : list) {
                String id=getId(t).toString();
                JSONObject conditionObj=new JSONObject();
                conditionObj.put("_index",indexName);
                conditionObj.put("_type",type);
                conditionObj.put("_id",id);
                JSONObject optionObj=new JSONObject();
                optionObj.put("update",conditionObj);
                String optionJson=optionObj.toJSONString();

                queryBody+=optionJson+"\n";

                String dataJson = mapperJson(null,JsonEncoder.DEFAULT.encode(t),t.getClass(),false);
                JSONObject updateObject=new JSONObject();
                updateObject.put("doc", JSONObject.parse(dataJson));
                updateObject.put("doc_as_upsert",true);

                String updateJson=updateObject.toJSONString();

                queryBody+=updateJson+"\n";
            }

            HttpEntity entity = new NStringEntity(queryBody, ContentType.APPLICATION_JSON);
            Request request =new Request(RestRequest.Method.POST.name(),endpoint);
            request.setEntity(entity);
            Response response = restClient.performRequest(request);
            String responseBody = EntityUtils.toString(response.getEntity());
            JSONObject responseObject = JSON.parseObject(responseBody);
            boolean errors= (boolean)(responseObject.get("errors") != null?responseObject.get("errors"):false);
            if (errors){
                log.error("update or insert es error，error is："+(String)responseObject.get("items"));
                throw  new RuntimeException("update or insert es error，error is "+(String)responseObject.get("items"));
            }

        }catch (Exception e){
            log.error("update or insert es error:{}",e.getMessage(),e);
            throw  new RuntimeException("update or insert es error，error is "+e.getMessage());
        }
    }

    /**
     * 通过query 删除数据
     * @param query
     * @param cls
     * @param <M>
     * @return
     */
    public <M> long deleteByQuery(String query,Class<M> cls){
        String indexName=getIndex(cls);
        String type = getType(cls);
       log.debug(query);

        String method = "DELETE";
        //String endpoint = "/"+indexName+"/"+type+"/"+id;  //id的方法待实现  注解反射去做
        String endpoint = "/"+indexName+"/"+type+"/_delete_by_query";
        try {
            HttpEntity queryEntity = new NStringEntity(query, ContentType.APPLICATION_JSON);
            Request request =new Request(RestRequest.Method.DELETE.name(),endpoint);
            request.setEntity(queryEntity);
            Response response = restClient.performRequest(request);
        }catch (Exception e){
            log.error("delete es error:{}",e.getMessage());
        }
        return 1;
    }

    /**
     * 通过queryId删除数据
     * @param queryId 查询Id
     * @param params 参数
     * @param cls
     * @param <M>
     * @return
     */
    public <M> long deleteByQuery(String queryId,Map<String,Object> params,Class<M> cls){
        String query=buildQuery(queryId,params,cls);
        return deleteByQuery(query,cls);
    }

    /**
     * 通过主键删除数据
     * @param key
     * @param cls
     * @param <M>
     * @return
     */
    public <M> long deleteByPrimaryKey (String key,Class<M> cls){
        String indexName=getIndex(cls);
        String type = getType(cls);
        String method = "DELETE";
        String endpoint = "/"+indexName+"/"+type+"/"+key;
        try {
            Request request =new Request(RestRequest.Method.DELETE.name(),endpoint);
            //request.setEntity(entity);
            Response response = restClient.performRequest(request);
        }catch (Exception e){
            log.error("delete es error:{}",e.getMessage());
        }
        return 1;
    }

    /**
     * 通过主键更新数据
     * @param m
     * @param <M>
     * @return
     */
    public <M> long updateByPrimaryKey (M m){
        String indexName=getIndex(m.getClass());
        String type = getType(m.getClass());

        //反射取得ID注解的值
        String id=getId(m).toString();
        String method = "POST";
        String endpoint = "/"+indexName+"/"+type+"/"+id+"/_update";
        try {
            //String dataJson=JsonEncoder.DEFAULT.encode(m);
            JSONObject updateObject=new JSONObject();
            updateObject.put("doc",m);
            String json=updateObject.toJSONString();
            json=mapperJson(null,json,m.getClass(),false);
            HttpEntity entity = new NStringEntity(json, ContentType.APPLICATION_JSON);
            Request request =new Request(RestRequest.Method.POST.name(),endpoint);
            request.setEntity(entity);
            Response response = restClient.performRequest(request);
        }catch (Exception e){
            log.error("update es error:{}",e.getMessage());
        }
        return 1;
    }

    /**
     * 通过主键按照query更新数据
     * @param key 主键
     * @param query 更新json
     * @param cls
     * @param <M>
     * @return
     */
    public <M> long updateByPrimaryKeyQuery(String key,String query,Class<M> cls){
        String indexName=getIndex(cls);
        //String type = getType(cls);

        //反射取得ID注解的值
        //String id=getId(m).toString();
        String method = "POST";
        String endpoint = "/"+indexName+"/"+type+"/"+key+"/_update";
        try {
            HttpEntity entity = new NStringEntity(query, ContentType.APPLICATION_JSON);
            Request request =new Request(RestRequest.Method.POST.name(),endpoint);
            request.setEntity(entity);
            Response response = restClient.performRequest(request);
            //Response response = restClient.performRequest(method, endpoint, Collections.emptyMap(), entity);
        }catch (Exception e){
            log.error("update es error:{}",e.getMessage());
        }
        return 1;
    }


    private <E> Map<String,Object> handlerResponseBody(String responseBody,Class<E> cls){
        Map<String,Object> resultMap=new HashMap<>();
        if (null!=responseBody) {
            JSONObject responseObject = JSON.parseObject(responseBody);
            if (null != restClient) {
                JSONObject hitsObject = JSON.parseObject(responseObject.get("hits").toString());//外层hits
                //int totalSize = hitsObject.getInteger("total");
                int totalSize =JSON.parseObject(hitsObject.getString("total")).getInteger("value");
                resultMap.put(KEY_TOTAL,totalSize);
                if (totalSize > 0) {
                    JSONArray hitsArray = JSON.parseArray(hitsObject.get("hits").toString());//内部hits
                    if (hitsArray.size() > 0) {
                        List<E> rows = new ArrayList<>();
                        for (int i = 0; i < hitsArray.size(); i++) {
                            JSONObject row = hitsArray.getJSONObject(i);
                            String _source = row.get("_source").toString();
                            String _id = row.get("_id").toString();
                            _source = mapperJson(_id, _source, cls, true);
                            E e = JsonEncoder.DEFAULT.decode(_source, cls);
                            rows.add(e);
                        }
                        resultMap.put(KEY_ROWS,rows);
                    }
                }
            } else {//2.x
                JSONObject hitsObject = JSON.parseObject(responseObject.get("hits").toString());//外层hits
                int totalSize = hitsObject.getInteger("totalHits");
                resultMap.put(KEY_TOTAL,totalSize);
                if (totalSize > 0) {
                    JSONArray hitsArray = JSON.parseArray(hitsObject.get("hits").toString());//内部hits
                    if (hitsArray.size() > 0) {
                        List<E> rows = new ArrayList<>();
                        for (int i = 0; i < hitsArray.size(); i++) {
                            JSONObject row = hitsArray.getJSONObject(i);
                            String _source = row.get("source").toString();
                            String _id = row.get("id").toString();
                            _source = mapperJson(_id, _source, cls, true);
                            E e = JsonEncoder.DEFAULT.decode(_source, cls);
                            rows.add(e);
                        }
                        resultMap.put(KEY_ROWS,rows);
                    }
                }
            }
        }
        return resultMap;

    }


    private long getEsMaxResultWindow(Class clazz){
        if (0==MAX_RESULT_WINDOW){
            String indexName=getIndex(clazz);
            String method = "GET";
            String endpoint = "/"+indexName+"/_settings";
            try {
                HttpEntity entity = new NStringEntity("", ContentType.APPLICATION_JSON);
                Request request =new Request(RestRequest.Method.GET.name(),endpoint);
                request.setEntity(entity);
                Response response = restClient.performRequest(request);
                //Response response = restClient.performRequest(method,endpoint,Collections.emptyMap(),entity);
                String responseBody = EntityUtils.toString(response.getEntity());
                JSONObject responseObject = JSON.parseObject(responseBody);
                JSONObject indexObject = JSON.parseObject(responseObject.get(indexName).toString());//外层hits
                JSONObject settingsObject= JSON.parseObject(indexObject.get("settings").toString());
                JSONObject dataObj= JSON.parseObject(settingsObject.get("index").toString());
                MAX_RESULT_WINDOW= Long.valueOf(dataObj.get("max_result_window").toString());
            }catch (Exception e){
                MAX_RESULT_WINDOW=10000L;
                log.error("getEsMaxResultWindow error:{}",e.getMessage());
                //e.printStackTrace();
            }
        }
        return MAX_RESULT_WINDOW;
    }

    /**
     * 将请求参数追加分页参数
     * @param query
     * @param pager
     * @return
     */
    private String queryAddPager(String query,Pager pager){
        pager=resetPager(pager);
        //long max=getEsMaxResultWindow();
        int from=(pager.getPage()-1)*pager.getSize();
        /*if (from>max){
            from=(int)max-pager.getSize();
            log.error("最大页超过限制，最大索引值 max_result_window：{}",max);
        }*/
        //System.out.println(query);
        JSONObject queryJson = JSON.parseObject(query);

        queryJson.fluentPut("from",from);
        queryJson.fluentPut("size",pager.getSize());

        query=queryJson.toJSONString();
        return query;
    }

    private Pager resetPager(Pager pager){
        //暂时不做最大分页限制
        /*long max=getEsMaxResultWindow();
        if (pager.getPage()*pager.getSize()>max){
            long maxPage=0;
            if (pager.getSize()==0){
                maxPage=0;
            }else{
                if (max%pager.getSize()!=0){
                    maxPage=max/pager.getSize()+1;

                }else{
                    maxPage=max/pager.getSize();
                }
            }
            pager.setPage((int)maxPage);
        }*/
        return pager;
    }

    /**
     * 拼接query
     * @param queryId
     * @param params
     * @param cls
     * @param <T>
     * @return
     */
    private <T> String buildQuery(String queryId,Map<String,Object> params,Class<T> cls){

        //String type = getType(cls);
        String index=getIndex(cls);
        String keyId=null;
        if (StringUtils.isNotBlank(index)){
            keyId="es."+index+"."+queryId;
        }else{
            keyId="es."+queryId;
        }
        String query= EsMapperParser.DEFAULT.getQuery(keyId,params);
        return query;
    }

    private <T> String  getIndex(Class<T> clazz){
        if(StringUtils.isNotEmpty(index)){
            return index;
        }
        IndexName indexName=clazz.getAnnotation(IndexName.class);
        if (null==indexName){
            log.error("未配置对象的 @IndexName 注解");
            return null;
        }
        String value = indexName.value();
        return value;
    }

    /**
     * 获取TYPE  1.6 只有一个type  1.7 没有type了
     * @param cls
     * @param <T>
     * @return
     */
    private <T> String getType(Class<T> cls){
        return "_doc";
    }
    /*private <T> String getType(Class<T> cls){
        if(StringUtils.isNotEmpty(type)){
            return type;
        }
        IndexType typeName=cls.getAnnotation(IndexType.class);
        if (null==typeName){
            log.debug("未配置对象的 @TypeName注解");
            return null;
        }
        String type = cls.getAnnotation(IndexType.class).value();
        return type;
    }*/



    /**
     * 获取ID
     * @param m
     * @param <M>
     * @return
     */
    private <M> Object getId(M m){
        Object id=null;
        MethodAccess methodAccess=MethodAccess.get(m.getClass());
        Field[] fs = m.getClass().getDeclaredFields();
        for(int i = 0 ; i < fs.length; i++){
            Field f = fs[i];
            String fName=f.getName();
            boolean indexIdFlag=false;
            for (Annotation anno : f.getDeclaredAnnotations()) {//获得所有的注解
                if(anno.annotationType().equals(IndexId.class) ) {//找到自己的注解
                    indexIdFlag=true;
                    break;
                }
            }
            if(indexIdFlag){
                String methodName = "get"+fName.substring(0, 1).toUpperCase() + fName.substring(1);
                Object idObj=methodAccess.invoke(m, methodName, null);
                id=idObj;
                break;
            }
        }
        return id;
    }


    /**
     * class 与 json映射
     * @param sourceJson
     * @param cls
     * @param toObjectFlag true 将json映射成 cls可以识别的 json。
     *                false 将json映射成 es可以存储的json。
     * @param <M>
     * @return
     */
    private <M> String mapperJson(String _id,String sourceJson,Class<M> cls,boolean toObjectFlag){
        if (toObjectFlag){
            JSONObject jsonObject= JSONObject.parseObject(sourceJson);
            jsonObject.put("_id",_id);
            sourceJson=jsonObject.toJSONString();
        }else{
            JSONObject jsonObject= JSONObject.parseObject(sourceJson);
            jsonObject.remove("_id");
            sourceJson=jsonObject.toJSONString();
        }

        Map<String,String> mapperMap=new HashMap<>();
        Field[] fs = cls.getDeclaredFields();
        for(int i = 0 ; i < fs.length; i++){
            Field f = fs[i];
            String fName=f.getName();
            for (Annotation anno : f.getDeclaredAnnotations()) {//获得所有的注解
                if(anno.annotationType().equals(IndexMapper.class) ) {//找到自己的注解
                    String mapperClm=((IndexMapper)anno).value();
                    mapperMap.put(fName,mapperClm);
                    break;
                }
            }
        }

        for (Map.Entry<String, String> entry : mapperMap.entrySet()) {
            if (toObjectFlag) {
                sourceJson= sourceJson.replaceAll("\"" + entry.getValue() + "\":", "\"" + entry.getKey() + "\":");
            }else{
                sourceJson= sourceJson.replaceAll("\"" + entry.getKey() + "\":", "\"" + entry.getValue() + "\":");
            }
        }
        return sourceJson;
    }


}
